package com.online.questionnaire.controller;

import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.online.questionnaire.common.ErrorCode;
import com.online.questionnaire.common.PageParam;
import com.online.questionnaire.common.R;
import com.online.questionnaire.common.ResultUtils;
import com.online.questionnaire.exception.BusinessException;
import com.online.questionnaire.exception.ThrowUtils;
import com.online.questionnaire.model.Surveys;
import com.online.questionnaire.model.User;
import com.online.questionnaire.model.dto.SurveyStatisticsDTO;
import com.online.questionnaire.model.dto.SurveysDTO;
import com.online.questionnaire.model.vo.UserSurveyStatistics;
import com.online.questionnaire.service.SurveySubmitService;
import com.online.questionnaire.service.SurveysService;
import com.online.questionnaire.service.UserService;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

import static com.online.questionnaire.constant.UserConstant.ADMIN_ROLE;

/**
 * @author administer
 */
@RestController
@RequestMapping("/surveys")
@Slf4j
@Tag(name = "问卷接口")
public class SurveysController extends BaseController<Surveys>{

    @Resource
    private SurveysService surveysService;
    @Resource
    UserService userService;
    @Resource
    SurveySubmitService surveySubmitService;

    @Override
    protected IService<Surveys> getService() {
        return surveysService;
    }

    @Override
    protected UserService getUserService() {
        return userService;
    }

    /**
     * 分页查询 自己创建的问卷
     * @param surveys
     * @param request
     * @return
     */
    @GetMapping("/page")
    @Override
    public R<IPage<Surveys>> page(PageParam param,Surveys surveys, HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (param.getPage() == null || param.getPage() <= 0){
            param.setPage(1);
        }
        if (param.getSize() == null || param.getSize() <= 0 || param.getSize() > 50){
            param.setSize(50);
        }

        LambdaQueryWrapper<Surveys> queryWrapper = new LambdaQueryWrapper<>();
        //只能查看自己创建的问卷 包括管理员
        queryWrapper.eq(Surveys::getCreateuserid,loginUser.getId());
        //模糊查询 问卷名字
        queryWrapper.like(StringUtils.isNotBlank(surveys.getTitle()),Surveys::getTitle,surveys.getTitle());
        queryWrapper.orderByDesc(Surveys::getCreatetime);
        //排除模板问卷
        queryWrapper.ne(Surveys::getIsTemplate,1);
        queryWrapper.eq(surveys.getStatus() != null,Surveys::getStatus,surveys.getStatus());
        Page<Surveys> pageInfo = surveysService.page(new Page<>(param.getPage(),param.getSize()),queryWrapper);

        for (Surveys surveys1 : pageInfo.getRecords()){
            surveys1.setSubmitNum(surveySubmitService.getSubmitNum(surveys1.getId()));
        }
        return ResultUtils.success(pageInfo);

    }

    /**
     * 获取用户问卷统计信息
     * @param request
     * @return
     */
    @GetMapping("/user-statistics")
    public R<UserSurveyStatistics> userStatistics(HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        UserSurveyStatistics userSurveyStatistics = surveysService.getUserSurveyStatistics(loginUser.getId());
        if (userSurveyStatistics != null){
            return ResultUtils.success(userSurveyStatistics);
        }else{
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"获取失败");
        }
    }

    /**
     * 保存试卷
     * @param surveys
     * @return
     */
    @PostMapping("/save")
    public R<SurveysDTO> save(@RequestBody SurveysDTO surveys, HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (surveys == null){
            ThrowUtils.paramsError("参数错误");
        }
        SurveysDTO surveysDTO = surveysService.updateSurveys(surveys, loginUser.getId());
        if (surveysDTO != null){
            return ResultUtils.success(surveysDTO);
        }else{
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"保存失败");
        }
    }


    /**
     * 复制问卷
     * @param id
     * @return
     */
    @PostMapping("/copy/{id}")
    public R<Boolean> copy(@PathVariable Long id, HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        boolean copy = surveysService.copy(id, loginUser);
        if (copy){
            return ResultUtils.success(copy);
        }else{
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"复制失败");
        }
    }

    /**
     * 根据id获取问卷DTO
     * @param id
     * @return
     */
    @GetMapping("/getDTO/{id}")
    public R<SurveysDTO> getDTOById(@PathVariable Long id){
        if (id == null){
            ThrowUtils.paramsError("参数错误");
        }
        SurveysDTO surveysDTO = surveysService.getDTOById(id);
        //设置创建用户名称
        if (surveysDTO.getCreateuserid() != null){
            surveysDTO.setCreateUserName(userService.getUserNameById(surveysDTO.getCreateuserid()));
        }
        if (surveysDTO != null){
            return ResultUtils.success(surveysDTO);
        }else{
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"获取失败");
        }
    }

    /**
     * 根据id获取问卷
     */
    @GetMapping("/get/{id}")
    public R<Surveys> getById(@PathVariable Long id){
        if (id == null){
            ThrowUtils.paramsError("参数错误");
        }
        Surveys surveys = surveysService.getById(id);
        //设置创建用户名称
        if (surveys.getCreateuserid() != null){
            surveys.setCreateUserName(userService.getUserNameById(surveys.getCreateuserid()));
        }
        if (surveys != null){
            return ResultUtils.success(surveys);
        }else{
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"获取失败");
        }
    }

//    /**
//     * 更新问卷信息
//     */
//    @PostMapping("/update")
//    public R<Boolean> update(@RequestBody Surveys surveys, HttpServletRequest request){
//        User loginUser = userService.getLoginUser(request);
//        if (loginUser == null){
//            ThrowUtils.notLoginError();
//        }
//        if (surveys == null){
//            ThrowUtils.paramsError("参数错误");
//        }
//
//        boolean update = surveysService.updateById(surveys);
//        if (update){
//            return ResultUtils.success(update);
//        }else{
//            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"更新失败");
//        }
//    }


    /**
     * 删除问卷 只能本人或管理员删除
     * @param id
     * @param request
     * @return
     */
    @GetMapping("/delete/{id}")
    public R<Boolean> delete(@PathVariable Long id, HttpServletRequest request) {
        if (id == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = getUserService().getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        Surveys byId = surveysService.getById(id);
        if (byId == null){
            return ResultUtils.error(ErrorCode.OPERATION_ERROR,"问卷不存在");
        }
        // 判断是否本人或管理员
        if (!loginUser.getId().equals(byId.getCreateuserid())
                && !ADMIN_ROLE.equals(loginUser.getUserRole())){
            return ResultUtils.error(ErrorCode.NO_AUTH_ERROR);
        }
        boolean remove = getService().removeById(id);
        if (!remove){
            return ResultUtils.error(ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success(remove);
    }


    /**
     * 统计单张问卷数据
     */
    @GetMapping("/statistics/{id}")
    public R<SurveyStatisticsDTO> statistics(@PathVariable Long id, HttpServletRequest request){
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (id == null){
            ThrowUtils.paramsError("参数错误");
        }
        //查看是否是自己的问卷 或者管理员
        if (!loginUser.getId().equals(surveysService.getById(id).getCreateuserid())
              && !ADMIN_ROLE.equals(loginUser.getUserRole())){
            ThrowUtils.throwIf(true,ErrorCode.NO_AUTH_ERROR);
        }
        SurveyStatisticsDTO surveyStatistics = surveysService.getSurveyStatistics(id, loginUser.getId());
        return ResultUtils.success(surveyStatistics);

    }

    /**
     * 获取问卷整体比例统计文件
     *
     */
    @GetMapping("/statistics/file/all/{id}")
    public R<String> statisticsFile(@PathVariable Long id, HttpServletRequest request,HttpServletResponse response) throws IOException {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (id == null){
            ThrowUtils.paramsError("参数错误");
        }
        //检查问卷是否属于自己
        Surveys surveys = surveysService.getById(id);
        if (surveys == null){
            ThrowUtils.paramsError("问卷不存在！");
        }
        if (!surveys.getCreateuserid().equals(loginUser.getId())){
            ThrowUtils.throwIf(true,ErrorCode.NO_AUTH_ERROR);
        }
        Map<String, String> stringStringMap = surveysService.exportExcel(id, loginUser.getId());
        String fileName = URLEncoder.encode(stringStringMap.get("name"), "UTF-8").replaceAll("\\+", "%20");  // 编码，并替换空格
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName);
        response.setHeader("Access-Control-Expose-Headers","Content-Disposition, X-Custom-Header");

        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(FileUtil.readBytes(stringStringMap.get("path")));
        outputStream.flush();
        outputStream.close();

        return ResultUtils.success(stringStringMap.get("name"));

    }

    /**
     * 获取问卷所有答卷统计文件
     *
     */
    @GetMapping("/statistics/file/list/{id}")
    public R<String> statisticsList(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws IOException {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null){
            ThrowUtils.notLoginError();
        }
        if (id == null){
            ThrowUtils.paramsError("参数错误");
        }
        //检查问卷是否属于自己
        Surveys surveys = surveysService.getById(id);
        if (surveys == null){
            ThrowUtils.paramsError("问卷不存在！");
        }
        if (!surveys.getCreateuserid().equals(loginUser.getId())){
            ThrowUtils.throwIf(true,ErrorCode.NO_AUTH_ERROR);
        }
        Map<String, String> stringStringMap = surveysService.exportExcelByOneAnswer(id, loginUser.getId());

        String fileName = URLEncoder.encode(stringStringMap.get("name"), "UTF-8").replaceAll("\\+", "%20");  // 编码，并替换空格
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition","attachment;filename=" + fileName);
        response.setHeader("Access-Control-Expose-Headers","Content-Disposition, X-Custom-Header");


        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(FileUtil.readBytes(stringStringMap.get("path")));
        outputStream.flush();
        outputStream.close();
        return ResultUtils.success(stringStringMap.get("name"));
    }

}
